


/** 保存游戏所有数据  包括数据处理 */
export  class AllData {

    /** 地图数据信息 */
    private MapData:Array<Array<number>> = new Array();

    /** 地图数据长度 */
    private MdataLen:number = 0;

    /** 可以消除的编号列表 */
    private eliminate_list:Array<Array<number>> = new Array();

    /** 合成的六边形等级 */
    private _level:number = 2;

    set Level(level:number){
        this._level = level;
    }

    get Level():number {
        return this._level;
    }

    set MapDatas(data:Array<Array<number>>){

        this.MapData = data;
    }

    get MapDatas (){

        return this.MapData;
    }

    public clearEliminate_list (){
        this.eliminate_list = [];
    }

    constructor(){
        
    }

    /** 将下标转化为数据地图数据下标 */
    public ConvertNumberingTodata (isubscript:number){

        let index = 0;
        for(let i=0;i<this.MapData.length;i++){
            for(let j=0;j<this.MapData[i].length;j++){
                if(index == isubscript){
                    return [i,j];
                }
                index++;                
            }
        }
    }
 
    
    /** 将下标转化为数据 */
    public ConvertdataToNumber (isubscript:Array<number>){
        if(isubscript.length != 2){
            return;
        }
        let index = 0;
        for(let i=0;i<this.MapData.length;i++){
            for(let j=0;j<this.MapData[i].length;j++){
                if(i == isubscript[0] && j == isubscript[1]){
                    return index;
                }
                index++;
            }
        }
    }
    
    public addMapData(level:number,isubscript:Array<number>){
        this.MapData[isubscript[0]][isubscript[1]] = level;
    }

    public ClearSingle (isubscript:Array<number>){
        if(isubscript.length != 2){
            return;
        }
        this.MapData[isubscript[0]][isubscript[1]] = 0;
    }

    public ClearAllmapData (){
        for(let i=0;i<this.MapData.length;i++){
            for(let j=0;j<this.MapData[i].length;j++){
                this.MapData[i][j] = 0;
            }
        }
    }    

    public canPlace(index:number){
        let data = this.ConvertNumberingTodata(index);
        if(this.MapData[data[0]][data[1]]){
            return true;
        }else{
            return false;
        }
        
    }

    /**
     *  计算所有能消除的位置
     * @param isubscript 遍历的首要位置
     * @param level 可消除等级
     */
    public CalculatesAll (isubscript:Array<number>){

        this.eliminate_list = [];
        this.MdataLen = this.MapData.length;
        let level = this.MapData[isubscript[0]][isubscript[1]];
        if(level <= 0){
            cc.warn("所需要遍历的等级错误");
            return [];
        }
        return this.CalculatesAllsquares(isubscript,level);
    }

    /**
     * 计算所有能消除的数据 递归遍历所有位置
     * @param isubscript 起始遍历位置坐标
     */
    public CalculatesAllsquares (isubscript:Array<number>,level:number){
        if(isubscript.length != 2){
            return;
        }
        let x = isubscript[0];
        let y = isubscript[1];
        if(x < 0 || x >= this.MapData.length){
            return;
        }
        if(y <0 || y >= this.MapData[x].length){
            return;
        }
        let maxCount = this.MapData[x].length;
        if(x < Math.floor(this.MdataLen/2)){
            //左上角元素
            if(x-1 >= 0 &&  y-1 >=0){
                if(this.MapData[x-1][y-1] == level){
                    if(!this.isRepeatColorForClear(x-1,y-1)){
                        this.eliminate_list.push([x-1,y-1]);
                        this.CalculatesAllsquares([x-1,y-1],level);
                    }           
                }
            }
            //右上
            if(x-1 >= 0 && y < maxCount){
                if(this.MapData[x-1][y] == level){
                    if(!this.isRepeatColorForClear(x-1,y)){
                        this.eliminate_list.push([x-1,y]);
                        this.CalculatesAllsquares([x-1,y],level);
                    }  
                    
                }
            }
            //右下
            if(x+1 < this.MapData.length && y+1 < maxCount){
                if(this.MapData[x+1][y+1] == level){
                    if(!this.isRepeatColorForClear(x+1,y+1)){
                        this.eliminate_list.push([x+1,y+1]);
                        this.CalculatesAllsquares([x+1,y+1],level);
                    }       
                }
            }
            //左下角元素
            if(x+1 < this.MapData.length && y < maxCount){
                if(this.MapData[x+1][y] == level){
                    if(!this.isRepeatColorForClear(x+1,y)){
                        this.eliminate_list.push([x+1,y]);
                        this.CalculatesAllsquares([x+1,y],level);
                    }  
                }
            }
             
        }else if(x == Math.floor(this.MdataLen/2)){
            //左上角元素
            if(x-1 >= 0 &&  y-1 >=0){
                if(this.MapData[x-1][y-1] == level){
                    if(!this.isRepeatColorForClear(x-1,y-1)){
                        this.eliminate_list.push([x-1,y-1]);
                        this.CalculatesAllsquares([x-1,y-1],level);
                    }           
                }
            }
            //右上
            if(x-1 >= 0 && y < maxCount){
                if(this.MapData[x-1][y] == level){
                    if(!this.isRepeatColorForClear(x-1,y)){
                        this.eliminate_list.push([x-1,y]);
                        this.CalculatesAllsquares([x-1,y],level);
                    }  
                    
                }
            }
            //右下
            if(x+1 < this.MapData.length && y < maxCount){
                if(this.MapData[x+1][y] == level){
                    if(!this.isRepeatColorForClear(x+1,y)){
                        this.eliminate_list.push([x+1,y]);
                        this.CalculatesAllsquares([x+1,y],level);
                    }  
                } 
            }
            //左下
            if(x+1 < this.MapData.length && y-1 >= 0){
                if(this.MapData[x+1][y-1] == level){
                    if(!this.isRepeatColorForClear(x+1,y-1)){
                        this.eliminate_list.push([x+1,y-1]);
                        this.CalculatesAllsquares([x+1,y-1],level);
                    }  
                } 
            }

        }else{
            //下半区
            //左上角元素
            if(x-1 >= 0 &&  y >= 0){
                if(this.MapData[x-1][y] == level){
                    if(!this.isRepeatColorForClear(x-1,y)){
                        this.eliminate_list.push([x-1,y]);
                        this.CalculatesAllsquares([x-1,y],level);
                    }           
                }
            }
            //右上
            if(x-1 >= 0 && y+1 < maxCount){
                if(this.MapData[x-1][y+1] == level){
                    if(!this.isRepeatColorForClear(x-1,y+1)){
                        this.eliminate_list.push([x-1,y+1]);
                        this.CalculatesAllsquares([x-1,y+1],level);
                    }  
                    
                }
            }
            
            //右下
            if(x+1 < this.MapData.length && y < maxCount){
                if(this.MapData[x+1][y] == level){
                    if(!this.isRepeatColorForClear(x+1,y)){
                        this.eliminate_list.push([x+1,y]);
                        this.CalculatesAllsquares([x+1,y],level);
                    }  
                } 
            }
            //左下
            if(x+1 < this.MapData.length && y-1 >= 0){
                if(this.MapData[x+1][y-1] == level){
                    if(!this.isRepeatColorForClear(x+1,y-1)){
                        this.eliminate_list.push([x+1,y-1]);
                        this.CalculatesAllsquares([x+1,y-1],level);
                    }  
                } 
            }
        }
        //左边元素
        if(x < this.MapData.length && y-1 >= 0){
            if(this.MapData[x][y-1] == level){
                if(!this.isRepeatColorForClear(x,y-1)){
                    this.eliminate_list.push([x,y-1]);
                    this.CalculatesAllsquares([x,y-1],level);
                }  
            }
        } 
        //右
        if(x < this.MapData.length && y+1 < maxCount){
            if(this.MapData[x][y+1] == level){
                if(!this.isRepeatColorForClear(x,y+1)){
                    this.eliminate_list.push([x,y+1]);
                    this.CalculatesAllsquares([x,y+1],level);
                }  
            } 
        }
        // //组内元素去重
        // this.eliminate_list = this.unique(this.eliminate_list);
        let eleme_list = [];
        for(let i=0;i<this.eliminate_list.length;i++){
            let index = this.ConvertdataToNumber(this.eliminate_list[i]);
            eleme_list.push(index);
        }
        return eleme_list;
    }

    //是否有重复的加入同一个坐标的六边形
    isRepeatColorForClear(x,y){
        for(var i = 0;i < this.eliminate_list.length;i++){
            if(this.eliminate_list[i][0] == x && this.eliminate_list[i][1] == y){
                return true;
            }
        }
        return false;
    }

    private unique(arr){
        var newArr = [];
        for(var i in arr) {
            if(newArr.indexOf(arr[i]) == -1) {      //indexOf() :返回某个指定的字符串值在字符串中首次出现的位置。如果没有则返回-1
                newArr.push(arr[i])
            }
        }
        return newArr;
    }

    /** 消除周围数据进行合成升级 */
    public EliminateUpgrade (beginIndex:number,elements:Array<number>){

        let data = this.ConvertNumberingTodata(beginIndex);
        let level = this.MapData[data[0]][data[1]];
        this.MapData[data[0]][data[1]] = level*2;
        for(let i=0;i<elements.length;i++){
            let eliminate = this.ConvertNumberingTodata(elements[i]);
            if(this.MapData[eliminate[0]][eliminate[1]] == level){
                this.ClearSingle(eliminate);
            }           
        }

        //刷新等级
        if(level*2 > this.Level){
            this.Level = level*2;
        }
    }

    public getLevel(pos:number){
        let data = this.ConvertNumberingTodata(pos);
        return this.MapData[data[0]][data[1]];
    }

    
    /**
     * 通过位置标号来检测类型
     * @param pos 用于判断类型的位置列表 必须是包含两个元素
     */
    public deteType (pos:Array<number>){

        if(pos.length != 2){
            cc.warn("传入类型不对");
        }
        let data_1 = this.ConvertNumberingTodata(pos[0]);  
        let data_2 = this.ConvertNumberingTodata(pos[1]);

        if(data_1[0] == data_2[0] && Math.abs(data_1[1] - data_2[1]) == 1){
            return 3;
        }else if(data_1[1] == data_2[1] && Math.abs(data_1[0] - data_2[0]) == 1){
            if(data_1[0] >= 3 && data_2[0] > 3){
               return 1;
            }else{
               return 2;
            }          
        }else if(Math.abs(data_1[0] - data_2[0]) == 1 && Math.abs(data_1[1] - data_2[1]) == 1 ){
            if(data_1[0] >= 3 && data_2[0] > 3){
                return 2;
            }else{
                return 1;
            } 
        }else{
            return 0;
        }
    }

    /** 通过地图数据判断游戏是否结束 */
    public isGameOver (){
        let data = {
            havepos:false,
            type:[],
        };
        let type = [];
        for(let i=0;i<this.MapData.length;i++){
            let maxCount = this.MapData[i].length;
            for(let j=0;j<this.MapData[i].length;j++){
                let level = this.MapData[i][j];
                if(level == 0){
                    type.push(0);
                    data.havepos = true;
                }
                //右边元素
                if(i < this.MapData.length && j+1 < maxCount){
                    if(this.MapData[i][j+1] == 0){
                        type.push(1);
                        type = this.unique(type);
                        data.havepos = true;
                        data.type = type;
                    }
                }
                //左下角元素
                if(i+1 < this.MapData.length && j < maxCount){
                    if(this.MapData[i+1][j] == 0){
                        type.push(2);
                        type = this.unique(type);
                        data.havepos = true;
                        data.type = type;
                    }
                }
                //右下角元素
                if(i+1 < this.MapData.length && j+1 < maxCount){
                    if(this.MapData[i+1][j+1] == 0){
                        type.push(3);
                        type = this.unique(type);
                        data.havepos = true;
                        data.type = type;
                    }
                }
            }
        }
        if(type.length == 0){
            data.havepos = false;
            return data;
        }else{
            type = this.unique(type);
            data.havepos = true;
            data.type = type;
            return data;
        }
        
    }

}
